package com.ship.dispatch.controller.orderPay;

import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ship.common.core.base.Page;
import com.ship.common.core.domain.R;
import com.ship.common.core.exception.BusException;
import com.ship.common.core.utils.FileUtils;
import com.ship.common.core.utils.StringUtil;
import com.ship.common.core.utils.StringUtils;
import com.ship.common.core.web.domain.BaseResultCode;
import com.ship.common.core.web.domain.JsonResult;
import com.ship.common.log.annotation.Log;
import com.ship.common.log.enums.BusinessType;
import com.ship.common.security.utils.SecurityUtils;
import com.ship.dispatch.bean.fob.SpFobFileRecord;
import com.ship.dispatch.bean.orderPay.SpPaymentOrder;
import com.ship.dispatch.model.dto.orderPay.SpPaymentOrderDetailDto;
import com.ship.dispatch.model.dto.orderPay.SpPaymentOrderDto;
import com.ship.dispatch.service.ExportService;
import com.ship.dispatch.service.fob.SpFobFileRecordService;
import com.ship.dispatch.service.orderPay.SpPaymentOrderService;
import com.ship.dispatch.vo.orderPay.*;
import com.ship.system.api.RemoteFileService;
import com.ship.system.api.domain.SysFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author gw
 * @title SpPaymentOrderController
 * @description 支付结算接口
 * @create 2023/12/29 0013
 */
@RestController
@RequestMapping("/order")
@Api(value = "spPaymentOrder", tags = "支付结算接口")
public class SpPaymentOrderController {
    @Autowired
    private SpPaymentOrderService orderService;

    @Autowired
    private ExportService exportService;

    @Autowired
    SpFobFileRecordService spFobFileRecordService;
    @Value("${file_server.host}")
    private String fileServerHost;
    @Autowired
    private RemoteFileService remoteFileService;
    private static final String FILE_UPLOAD_PATH = "/group1/upload";


    /**
     * 根据航次号和订单类型获取上传发票时间
     *
     * @return
     */
    @GetMapping("/getInvoiceTime/{dispatchSchemeExecuteId}/{orderType}/{contractId}")
    public JsonResult getInvoiceTime(@PathVariable(value = "dispatchSchemeExecuteId") Long dispatchSchemeExecuteId
            , @PathVariable(value = "orderType") Integer orderType
            , @PathVariable(value = "contractId") Long contractId) {
        String invoiceTime = orderService.getInvoiceTime(dispatchSchemeExecuteId, orderType,contractId);
        return JsonResult.success(invoiceTime);
    }

    /**
     * 获取订单类型
     *
     * @param labelName 名称
     * @return
     */
    @GetMapping(value = {"/getOrderTypes/{labelName}", "/getOrderTypes"})
    public JsonResult getOrderTypes(@PathVariable(value = "labelName", required = false) String labelName) {
        List<OrderTypesVO> orderTypesVOS = orderService.getOrderTypes(labelName);
        return JsonResult.success(orderTypesVOS);
    }

    /**
     * 获取航次号
     *
     * @return
     */
    @GetMapping("/getVoyageNos")
    public JsonResult getVoyageNos() {
        List<SpDispatchSchemeExecuteVO> spDispatchSchemeExecuteVOS = orderService.getVoyageNos();
        return JsonResult.success(spDispatchSchemeExecuteVOS);
    }

    /**
     * 获取合同集合
     *
     * @param constValue 订单类型
     * @return
     */
    @GetMapping(value = {"/getContracts/{constValue}", "/getContracts"})
    public JsonResult getContracts(@PathVariable(value = "constValue", required = false) Integer constValue) {
        List<ContractsVO> contractsVOS = orderService.getContracts(constValue);
        return JsonResult.success(contractsVOS);
    }

    /**
     * 新增订单
     *
     * @return
     */
    @PostMapping("/savePayOrder")
    @Log(title = "新增订单",businessType = BusinessType.INSERT)
    @ApiOperation(value = "新增订单")
    public JsonResult savePayOrder(@RequestBody @Validated SpPaymentOrderDto spPaymentOrderDto) {
        if (StringUtils.isEmpty(spPaymentOrderDto.getOrderTypeText())){
            return JsonResult.failed("订单类型不能为空");
        }
        if(null != spPaymentOrderDto.getPayAmount()){
            if(spPaymentOrderDto.getPayAmount().toString().length()>11){
                return JsonResult.failed("金额输入过长,请核实");
            }
        }
        Boolean judge = orderService.savePayOrder(spPaymentOrderDto);
        if (judge) {
            return JsonResult.success();
        } else {
            return JsonResult.failed("新增订单失败");
        }
    }

    /**
     * 删除订单
     *
     * @return
     */
    @DeleteMapping("/removePayOrder/{id}")
    @Log(title = "删除订单",businessType = BusinessType.DELETE)
    public JsonResult removePayOrder(@PathVariable(value = "id") Long id) {
        Boolean judge = orderService.removePayOrder(id);
        if (judge) {
            return JsonResult.success("删除成功");
        } else {
            return JsonResult.failed("删除订单失败");
        }
    }

    /**
     * 获取支付结算订单详情
     * 支付结算数据导出
     *
     * @return
     */
    @GetMapping("/getSpPaymentOrderDetail/{orderId}")
    public JsonResult getSpPaymentOrderDetail(@PathVariable(value = "orderId") Long orderId) {
        SpPaymentOrderDetailVO paymentOrderDetailVO = orderService.getSpPaymentOrderDetail(orderId);
        return JsonResult.success(paymentOrderDetailVO);
    }

    /**
     * 查询支付结算列表
     *
     * @return
     */
    @PostMapping("/page")
    public JsonResult<Page<SpPaymentOrder>> getPayOrders(@RequestBody SpPaymentOrder spPaymentOrder) {
        Page<SpPaymentOrder> page = orderService.page(spPaymentOrder, new QueryWrapper<>());
        return JsonResult.success(page);
    }

    /**
     * 支付结算数据导出
     *
     * @return
     */
    @ApiOperation(value = "支付结算数据导出")
    @PostMapping("/page/export")
    @Log(title = "支付结算数据导出",businessType = BusinessType.EXPORT)
    public JsonResult getPayOrdersExport(@RequestBody SpPaymentOrder spPaymentOrder) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        if(spPaymentOrder.getIds() != null && spPaymentOrder.getIds().size() > 0){
            queryWrapper.in("id",spPaymentOrder.getIds());
        }
        List<SpPaymentOrder> exportList = orderService.pageExportList(spPaymentOrder, queryWrapper, new LinkedList<>());
        for (SpPaymentOrder order : exportList) {
            order.setOrderStatusStr(order.getOrderStatusStr());
            order.setOrderTypeStr(order.getOrderTypeStr());
            order.setPayAmountStr(order.getPayAmountStr());
            order.setPayAmountUnitStr(order.getPayAmountUnitStr());
            order.setPayEndTimeStr(order.getPayEndTimeStr());
        }
        Field[] fields = SpPaymentOrder.class.getDeclaredFields();
        String url = exportService.pageExport(exportList,fields,exportService.listStrByModuleAndUser
                ("sp_payment_order",SecurityUtils.getUserId()), "支付结算信息");
        return JsonResult.success(url);
    }

    /**
     * 编辑支付结算订单详情
     *
     * @return
     */
    @PostMapping("/updateSpPaymentOrderDetail")
    @Log(title = "编辑支付结算订单",businessType = BusinessType.UPDATE)
    public JsonResult updateSpPaymentOrderDetail(@RequestBody @Validated SpPaymentOrderDetailDto paymentOrderDetailDto) {
        SpPaymentOrderDetailVO paymentOrderDetail = orderService.updateSpPaymentOrderDetail(paymentOrderDetailDto);
        return JsonResult.success(paymentOrderDetail);
    }

    /**
     * 上传支付结算附件
     *
     * @param file
     * @param orderDetailId
     * @return
     */
    @PostMapping("/upload")
    @Log(title = "上传支付结算附件",businessType = BusinessType.IMPORT)
    public JsonResult upload(@RequestParam("file") MultipartFile file, @RequestParam(value = "orderDetailId") String orderDetailId) {
        FileUtils.checkFileName(file);
        try {
            R<SysFile> result = remoteFileService.upload(file);
            if(result.getCode() != R.SUCCESS){
                throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
            }
            SpFobFileRecord spFobFileRecord = new SpFobFileRecord();
            spFobFileRecord.setPath(result.getData().getHttpsUrl());
            spFobFileRecord.setHttpPath(result.getData().getHttpUrl());
            spFobFileRecord.setName(file.getName());
            spFobFileRecord.setFileType("支付结算类");
            spFobFileRecord.setOrderDetailId(Long.valueOf(orderDetailId));
            spFobFileRecord.setCreateDate(new Date());
            spFobFileRecord.setCreateBy(SecurityUtils.getStringUserId());
            spFobFileRecordService.save(spFobFileRecord);
            List<OrderAttachmentsVO> orderAttachmentsVOS = new ArrayList<>();
            List<SpFobFileRecord> spFobFileRecords = spFobFileRecordService.getBaseMapper().selectList(new LambdaQueryWrapper<SpFobFileRecord>()
                    .eq(SpFobFileRecord::getOrderDetailId, Long.valueOf(orderDetailId))
            );
            if (null != spFobFileRecords) {
                spFobFileRecords.stream().forEach(s -> {
                    OrderAttachmentsVO orderAttachmentsVO = new OrderAttachmentsVO();
                    BeanUtils.copyProperties(s, orderAttachmentsVO);
                    orderAttachmentsVOS.add(orderAttachmentsVO);
                });
            }
            return JsonResult.success(orderAttachmentsVOS);
        } catch (Exception e) {
            return JsonResult.failed("上传失败，原因：" + e.getMessage());
        }
//        try {
//            Flux<DataBuffer> bufferFlux = file.content();
//            String name = file.filename();
//            Mono<List<OrderAttachmentsVO>> mono = bufferFlux.map(dataBuffer -> dataBuffer.asInputStream()).reduce(SequenceInputStream::new).flatMap(
//                    inputStream -> {
//                        String url = "";
//                        MultipartFile multipartFile = null;
//                        try {
//                            multipartFile = new MockMultipartFile("file", name, "application/octet-stream", inputStream);
//                        } catch (IOException e) {
//                            throw new RuntimeException(e);
//                        }
//                        R<SysFile> result1 = remoteFileService.upload(multipartFile);
//                        if(result1.getCode() != R.SUCCESS){
//                            throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
//                        }
//                        url = result1.getData().getHttpsUrl();
//                        file.delete().subscribe();
//                        SpFobFileRecord spFobFileRecord = new SpFobFileRecord();
//                        spFobFileRecord.setPath(url);
//                        spFobFileRecord.setName(name);
//                        spFobFileRecord.setFileType("支付结算类");
//                        spFobFileRecord.setOrderDetailId(Long.valueOf(orderDetailId));
//                        spFobFileRecord.setCreateDate(new Date());
//                        spFobFileRecord.setCreateBy(SecurityUtils.getStringUserId());
//                        spFobFileRecordService.save(spFobFileRecord);
//                        List<OrderAttachmentsVO> orderAttachmentsVOS = new ArrayList<>();
//                        List<SpFobFileRecord> spFobFileRecords = spFobFileRecordService.getBaseMapper().selectList(new LambdaQueryWrapper<SpFobFileRecord>()
//                                .eq(SpFobFileRecord::getOrderDetailId, Long.valueOf(orderDetailId))
//                        );
//                        if (null != spFobFileRecords) {
//                            spFobFileRecords.stream().forEach(s -> {
//                                OrderAttachmentsVO orderAttachmentsVO = new OrderAttachmentsVO();
//                                BeanUtils.copyProperties(s, orderAttachmentsVO);
//                                orderAttachmentsVOS.add(orderAttachmentsVO);
//                            });
//                        }
//                        return Mono.justOrEmpty(orderAttachmentsVOS);
//                    }
//            );
//            return JsonResult.success(mono.block());
//        } catch (Exception e) {
//            throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
//        }
    }

    /**
     * 上传附件M
     *
     * @return
     */
//    public String upload(MultipartFile file){
//        R<SysFile> result1 = remoteFileService.upload(file);
//        if(result1.getCode() != R.SUCCESS){
//            throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
//        }
//        String result = result1.getData().getHttpsUrl();;
//        return result;
//    }

    /**
     * 删除附件
     *
     * @param id
     * @return
     */
    @DeleteMapping("/deleteFile/{id}")
    @Log(title = "删除支付结算附件",businessType = BusinessType.DELETE)
    public JsonResult deleteFile(@PathVariable("id") Long id) {
        spFobFileRecordService.removeById(id);
        return JsonResult.success();
    }
}
